#!/usr/bin/env python
# -*- coding: utf-8 -*-

import Queue
import sqlite3
import threading


class SqliteMultithread(threading.Thread):

    """ SqliteMultithread """

    def __init__(self, filename, isolation_level='DEFERRED'):
        super(SqliteMultithread, self).__init__()
        self.filename = filename
        self.isolation_level = isolation_level
        self.req_queue = Queue.Queue()
        self.setDaemon(True)
        self.start()

    def run(self):
        with sqlite3.connect(self.filename, isolation_level=self.isolation_level) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            while True:
                command, args, res_queue = self.req_queue.get()
                if command == '--close--':
                    break
                if command == '--commit--':
                    conn.commit()
                else:
                    cursor.execute(command, args)
                    if res_queue:
                        for ret in cursor:
                            res_queue.put(ret)
                        res_queue.put('--no more--')

    def execute(self, command, args=None, res_queue=None):
        self.req_queue.put((command, args or tuple(), res_queue))

    def executemany(self, command, items):
        for item in items:
            self.execute(command, item)

    def select(self, command, args=None):
        res_queue = Queue.Queue()
        self.execute(command, args, res_queue)
        while True:
            ret = res_queue.get()
            if ret == '--no more--':
                break
            yield ret

    def select_one(self, command, args=None):
        try:
            return iter(self.select(command, args)).next()
        except StopIteration:
            return None

    def commit(self):
        self.execute('--commit--')

    def close(self):
        self.execute('--close--')
